
Aloísio Vítor
Image Processing Expert

Este tutorial proporciona un enfoque detallado y paso a paso para evitar las páginas de CAPTCHA y desafíos de AWS WAF utilizando PHP y la API de CapSolver. Detallamos la lógica para detectar respuestas de CAPTCHA (HTTP 405) y desafíos (HTTP 202), extraer los parámetros necesarios y utilizar el cookie aws-waf-token resultante para acceder al recurso protegido.
Bienvenido a este tutorial completo donde exploraremos el mundo de AWS CAPTCHA y cómo implementar un solucionador en PHP. Para desarrolladores y raspadores web, encontrarse con una CAPTCHA puede ser un obstáculo significativo, pero con las herramientas adecuadas, se convierte en una tarea manejable.
AWS WAF (Firewall de Aplicaciones Web) es un servicio de seguridad que ayuda a proteger aplicaciones web de explotaciones comunes. Ofrece dos acciones principales para verificar que una solicitud provenga de un usuario humano legítimo en lugar de un bot: CAPTCHA y Desafío.
| Acción | Propósito | Código de estado HTTP | Solución requerida |
|---|---|---|---|
| Desafío | Ejecuta una verificación silenciosa en segundo plano para confirmar que la sesión del cliente es un navegador estándar. | 202 Accepted |
Requiere resolver un desafío de JavaScript para obtener un token. |
| CAPTCHA | Requiere que el usuario final resuelva un rompecabezas visual para demostrar que es humano. | 405 Method Not Allowed |
Requiere resolver una CAPTCHA visual, que implica extraer parámetros específicos de la página. |
Una vez que se resuelva correctamente la CAPTCHA o el Desafío, AWS WAF emite un token válido, que se devuelve como el valor de una cookie llamada aws-waf-token. Esta cookie debe incluirse en las solicitudes posteriores para evitar la protección de WAF.
CapSolver ofrece una solución robusta de API para manejar tanto el Desafío silencioso como la CAPTCHA visual presentada por AWS WAF. Este tutorial se centra en el uso de la biblioteca cURL de PHP para implementar la lógica necesaria.
El núcleo de nuestra solución implica dos llamadas principales a la API de CapSolver: createTask para enviar la CAPTCHA/Desafío y getTaskResult para recuperar la solución.
<?php
// --- Configuración ---
$PROXY = "http://username:password@host:port"; // OPCIONAL: Reemplazar con los detalles de tu proxy (por ejemplo, para AntiAwsWafTask)
$PAGE_URL = "https://norway-meetup.aws.wslab.no/"; // Reemplazar con la URL objetivo protegida por AWS WAF
$CLIENT_KEY = "YourPayPerUsage"; // Reemplazar con tu clave de API de CAPSOLVER
/**
* Envía una tarea a la API de CapSolver.
* @param array $payload El payload de la tarea que contiene el tipo y los parámetros.
* @return array La respuesta de la API, incluyendo el taskId.
*/
function createTask($payload) {
global $CLIENT_KEY;
$ch = curl_init();
echo("Creando tarea...\n");
curl_setopt($ch, CURLOPT_URL, 'https://api.capsolver.com/createTask');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['clientKey' => $CLIENT_KEY, 'task' => $payload]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
/**
* Consulta la API de CapSolver para obtener el resultado de la tarea.
* @param string $taskId El ID de la tarea a verificar.
* @return array La respuesta de la API que contiene la solución.
*/
function getTaskResult($taskId) {
global $CLIENT_KEY;
do {
echo("Esperando solución...\n");
sleep(1);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.capsolver.com/getTaskResult');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['clientKey' => $CLIENT_KEY, 'taskId' => $taskId]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (isset($data['status']) && $data['status'] == "ready") {
return $data;
}
// Manejo de errores potenciales en getTaskResult
if (isset($data['errorId']) && $data['errorId'] != 0) {
echo("Error al recuperar el resultado de la tarea: " . $data['errorDescription'] . "\n");
return null;
}
} while(true);
}
/**
* Resuelve el Desafío o CAPTCHA de AWS WAF usando el tipo de tarea correspondiente.
* @param string $taskType El tipo de tarea de CapSolver (AntiAwsWafTask o AwsCaptchaTask).
* @param array $params Los parámetros necesarios para la tarea.
* @return string|null El valor de la cookie aws-waf-token o null en caso de fallo.
*/
function solveAwsWaf($taskType, $params) {
global $PAGE_URL, $PROXY;
$payload = [
'type' => $taskType,
'websiteURL' => $PAGE_URL,
'proxy' => $PROXY,
];
// Combinar parámetros específicos para la tarea
$payload = array_merge($payload, $params);
// Limpiar valores vacíos para una solicitud más limpia
$payload = array_filter($payload, function($value) {
return $value !== "" && $value !== null;
});
$taskData = createTask($payload);
if (isset($taskData['taskId'])) {
$result = getTaskResult($taskData['taskId']);
if ($result && isset($result['solution']['cookie'])) {
return $result['solution']['cookie'];
}
}
return null;
}
La lógica principal implica realizar una solicitud inicial a la página protegida y verificar el código de estado HTTP para determinar si se requiere un Desafío (202) o una CAPTCHA (405). Luego usamos expresiones regulares para extraer los parámetros necesarios del cuerpo de la respuesta HTML.
// --- Lógica de ejecución principal ---
// 1. Solicitud inicial a la página protegida
$ch = curl_init($PAGE_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$cookie = null;
echo("Código HTTP inicial: " . $httpCode . "\n");
if ($httpCode == 202) {
// --- Manejo del Desafío (202) ---
echo("Desafío detectado (HTTP 202). Extrayendo parámetros...\n");
// Extraer la URL de challenge.js
preg_match('/<script src="([^"]*token.awswaf.com[^"]*)"/', $response, $matches);
$awsChallengeJS = $matches[1] ?? null;
if ($awsChallengeJS) {
$params = ['awsChallengeJS' => $awsChallengeJS];
$cookie = solveAwsWaf("AntiAwsWafTask", $params);
} else {
echo("Error: awsChallengeJS no encontrado para el Desafío.\n");
}
} elseif ($httpCode == 405) {
// --- Manejo de CAPTCHA (405) ---
echo("CAPTCHA detectado (HTTP 405). Extrayendo parámetros...\n");
// Extraer parámetros del contenido de la página
preg_match('/<script src="([^"]*token.awswaf.com[^"]*)"/', $response, $matches);
$awsChallengeJS = $matches[1] ?? null;
preg_match('/"key":"(.*?)"/', $response, $matches);
$awsKey = $matches[1] ?? null;
preg_match('/"iv":"(.*?)"/', $response, $matches);
$awsIv = $matches[1] ?? null;
preg_match('/"context":"(.*?)"/', $response, $matches);
$awsContext = $matches[1] ?? null;
if ($awsKey && $awsIv && $awsContext) {
$params = [
'awsKey' => $awsKey,
'awsIv' => $awsIv,
'awsContext' => $awsContext,
'awsChallengeJS' => $awsChallengeJS // Opcional pero recomendado
];
// Nota: El tipo de tarea para la CAPTCHA visual suele ser aún AntiAwsWafTask,
// pero los parámetros pasados determinan el tipo de solución en el lado de CapSolver.
$cookie = solveAwsWaf("AntiAwsWafTask", $params);
} else {
echo("Error: Parámetros key, iv o context no encontrados para CAPTCHA.\n");
}
}
// 3. Usar el token para acceder al recurso protegido
if ($cookie) {
echo("Obtenido correctamente el aws-waf-token. Haciendo la solicitud final...\n");
$ch = curl_init($PAGE_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Establecer la cookie aws-waf-token
curl_setopt($ch, CURLOPT_COOKIE, "aws-waf-token=" . $cookie);
$finalResponse = curl_exec($ch);
curl_close($ch);
echo "\n--- Contenido de la página final ---\n";
echo $finalResponse;
echo "\n--------------------------\n";
} else {
echo("Fallo al resolver el desafío/CAPTCHA de AWS WAF.\n");
}
?>
El código original usaba funciones separadas (solveAwsChallenge, solveAwsCaptcha) y tenía nombres de parámetros ligeramente inconsistentes (key, iv, context vs. awsKey, awsIv, awsContext). El código optimizado lo simplifica en una sola función solveAwsWaf, asegurando coherencia con la documentación más reciente de la API de CapSolver para resolver AWS WAF. Este enfoque es más modular y fácil de mantener.
Esta lógica es altamente efectiva para tareas de raspado web y automatización. Para quienes trabajan en otros lenguajes, CapSolver también ofrece guías como "Cómo resolver AWS Captcha / Desafío con Python" [https://www.capsolver.com/blog/how-to-solve-aws-captcha-challenge-with-python] que siguen un patrón de API similar.
Los mecanismos de desafío y CAPTCHA de AWS WAF son medidas efectivas contra bots, pero no son insuperables. Al implementar una lógica robusta de detección y resolución en PHP, aprovechando la potencia de la API de CapSolver, los desarrolladores pueden obtener de manera confiable el valor de la cookie aws-waf-token para continuar con sus tareas de raspado o automatización sin interrupciones. La clave radica en identificar correctamente la acción de WAF a través del código de estado HTTP y extraer con precisión los parámetros necesarios del código fuente de la página.
aws-waf-token.AntiAwsWafTask maneja la resolución de Desafíos y CAPTCHAS, con los parámetros requeridos determinando la solución específica.preg_match es esencial para extraer parámetros dinámicos como awsChallengeJS, awsKey, awsIv y awsContext del código HTML.A: El código de estado HTTP es el indicador más confiable del tipo de acción de WAF requerida. Un código de estado 202 Accepted indica que hay un Desafío silencioso activo, que requiere pocos parámetros. Un código de estado 405 Method Not Allowed indica que hay una CAPTCHA visual activa, que requiere parámetros más específicos (key, iv, context) extraídos de las variables JavaScript de la página.
AntiAwsWafTask y AntiAwsWafTaskProxyLess?A: Ambos tipos de tarea están diseñados para resolver desafíos de AWS WAF. La principal diferencia es la necesidad de proxy. AntiAwsWafTask requiere que proporciones tu propio proxy en el payload de la solicitud. AntiAwsWafTaskProxyLess no requiere un proxy, ya que CapSolver maneja el uso del proxy internamente. Usar un proxy es generalmente recomendado para raspado a gran escala para mantener la anonimidad y evitar bloqueos de IP.
key, iv o context. ¿Qué debo hacer?A: Estos parámetros se generan dinámicamente y se incrustan en el código HTML, generalmente dentro de una etiqueta <script> o un campo oculto. Si tu preg_match falla, es probable que se deba a cambios en la implementación de WAF del sitio web objetivo. Deberías inspeccionar la fuente HTML más reciente de la página bloqueada para actualizar tus expresiones regulares.
A: Resolver manualmente los desafíos de AWS WAF es extremadamente difícil e impráctico para automatización. La acción de Desafío requiere ejecutar JavaScript complejo y obfuscado, y la acción de CAPTCHA requiere resolver rompecabezas de reconocimiento de imágenes. Los servicios de terceros como CapSolver usan inteligencia artificial avanzada e infraestructura a gran escala para resolver estos desafíos en tiempo real, haciendo posible la automatización. Intentar construir un solucionador interno para cada tipo de CAPTCHA generalmente no es rentable ni confiable.
aws-waf-token?A: El período de validez del aws-waf-token está determinado por la configuración de AWS WAF del sitio web protegido, pero generalmente es de 10 a 30 minutos. Una vez que el token expire, deberás repetir el proceso de resolución (solicitud inicial, detección y envío de tarea) para obtener un nuevo token.
Domina la resolución de desafíos de CAPTCHA de Amazon AWS WAF en la automatización del navegador con estrategias expertas. Aprende a integrar CapSolver para flujos de trabajo de automatización sin problemas y eficientes. Este guía cubre soluciones basadas en tokens y basadas en clasificación.

Este blog explica cómo se puede resolver el captcha de AWS WAF de manera rápida, barata y sencilla usando CapSolver
